﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microhard.FMCG.Buz.Interfaces;
using System.IO;
using System.Threading;
using System.Diagnostics;
using Microhard.Core;
using Microhard.FMCG.Buz.Models;
using System.Configuration;
using Microhard.FMCG.Buz.Impls;
using Microhard.Core.Mail;

namespace Microhard.FMCGClient
{
    public delegate void GetNewOrder(KASystemRunningModel info);
    public delegate void GetNewNews(KASystemRunningModel info);
    public delegate void NeedReLogin(KASystemRunningModel info);
    public delegate void OnKASystemError(KASystemRunningModel info);
    public delegate void OnSystemNotice(KASystemRunningModel info);
    public delegate void GetRunning(KASystemRunningModel info);
    public delegate void GetLoginInfo(KASystemRunningModel info);
    public delegate void GetNewStatements(KASystemRunningModel info);
    public delegate void GetOrderRecInfoError(KASystemRunningModel info);

    public class RunningMonitor
    {
        //使用单例模式
        public static readonly RunningMonitor Monitor = new RunningMonitor();
        private List<RunningModel> _running = new List<RunningModel>();
        private Timer timer;
        private string _interval = ConfigurationManager.AppSettings["QueryInterval"];
        private RunningMonitor()
        {
            //默认构造的时候，开始运行
            timer = new Timer(KASystemRun, null, int.Parse(_interval), Timeout.Infinite);
        }
        //多线程锁定
        private static readonly object _toLock = new object();
        /// <summary>
        /// 获得新订单
        /// </summary>
        public event GetNewOrder OnGetNewOrder;
        /// <summary>
        /// 获得新新闻
        /// </summary>
        public event GetNewNews OnGetNewNews;
        /// <summary>
        /// 需要重新登录
        /// </summary>
        public event NeedReLogin OnNeedReLogin;
        /// <summary>
        /// 系统错误
        /// </summary>
        public event OnKASystemError OnKASystemError;
        /// <summary>
        /// 供应商系统提示
        /// </summary>
        public event OnSystemNotice OnKASystemNotice;
        /// <summary>
        /// 普通运行信息
        /// </summary>
        public event GetRunning OnCommonRunning;
        /// <summary>
        /// 在登录中
        /// </summary>
        public event GetLoginInfo OnLogin;
        /// <summary>
        /// 销量信息
        /// </summary>
        public event GetNewStatements OnStatements;
        /// <summary>
        /// 获取到货信息失败
        /// </summary>
        public event GetOrderRecInfoError OnGetRecGoodInfoError;
        //用户登录相关信息
        public string SysuserLoginName { set; get; }
        public Guid SysuserCompanyID { set; get; }
        public bool IsLogin { set; get; }
        /// <summary>
        /// 开始运行
        /// </summary>
        private void KASystemRun(object e)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();

            //获得可以运行的system
            List<RunningModel> canRun;
            lock (_toLock)
            {
                canRun = _running.Where(r => r.CanRun == true).ToList();
            }
            #region 开始运行
            canRun.ForEach(i =>
            {
                bool hasEvent = false;
                var to = DateTime.Now;
                var from = to.AddDays(-4);
                bool isGetOrderError = false;
                bool isGetNewsError = false;
                bool isGetStatementError = false;
                bool IsGetRecGoodsInfoError = false;
                bool isGetOrderWithStoreError = false;

                #region 登录
                LoginResultModel loginResult = new LoginResultModel();
                if (!i.IsLogin)
                {
                    if (this.OnLogin != null)
                    {
                        i.Info.SystemNotice = "登录中";
                        this.OnLogin(i.Info);
                    }
                    loginResult = i.KASystem.Login(i.Info.UserName, i.Info.Passowrd, i.Info.ValidCode);
                    i.IsLogin = loginResult.IsSucceed;
                }

                if (i.IsLogin)
                {
                    //获得系统提示
                    if (loginResult.HasNotice && this.OnKASystemNotice != null)
                    {
                        i.Info.SystemNotice = loginResult.Notice;
                        hasEvent = true;
                        this.OnKASystemNotice(i.Info);
                    }
                    //获得订单
                    var norders = i.KASystem.GetOrder(from, to, out isGetOrderError);
                    if (norders.Count > 0 && this.OnGetNewOrder != null)
                    {
                        //生成订单明细
                        foreach (var o in norders.Where(w => w.OrderTypeName == "供应商订货单"))
                        {
                            o.Detail = i.KASystem.GetOrderDetail(o.Code, from, to, out isGetOrderWithStoreError);
                        }
                        i.Info.NewOrder = norders;
                        hasEvent = true;
                        this.OnGetNewOrder(i.Info);
                    }
                    //获得新闻
                    var news = i.KASystem.GetNews(out isGetNewsError);
                    if (news.Count > 0 && this.OnGetNewNews != null)
                    {
                        i.Info.TopNews = news;
                        hasEvent = true;
                        this.OnGetNewNews(i.Info);
                    }
                    //获得销量信息
                    //var amount = i.KASystem.GetMonthStatement(DateTime.Now, i.Info.UserName, out isGetStatementError);
                    //if (amount > 0)
                    //{
                    //    i.Info.AllStatementsAmount = amount;
                    //    hasEvent = true;
                    //    this.OnStatements(i.Info);
                    //}
                    //更新收货订单信息
                    //var recFrom = DateTime.Now.Date.AddMonths(-1);
                    //i.KASystem.UpdateGoodsReceiveInfo(recFrom, DateTime.Now, out IsGetRecGoodsInfoError);
                    //if (IsGetRecGoodsInfoError)
                    //{
                    //    hasEvent = true;
                    //    this.OnGetRecGoodInfoError(i.Info);
                    //}
                }
                else
                {
                    hasEvent = true;
                    i.Info.SystemNotice = "系统登录失败";
                    //失败则删除运行中的实例
                    _running.Remove(i);
                    this.OnNeedReLogin(i.Info);
                }
                #endregion

                if (isGetOrderError && isGetNewsError)
                {
                    if (this.OnKASystemError != null)
                    {
                        i.Info.SystemNotice = "供应商系统服务器错误，获取订单与新闻失败，请重新登录";
                        //失败则删除运行中的实例
                        _running.Remove(i);
                        this.OnKASystemError(i.Info);
                    }
                }
                else
                {
                    //如果没有事件，则提示普通运行信息
                    if (!hasEvent && this.OnCommonRunning != null)
                    {
                        i.Info.CommonInfo = "暂无任何新信息.运行时间:" + DateTime.Now;
                        //收集所有运行信息
                        i.Info.AllRunningDescription = "当前运行账户数:" + canRun.Count;
                        this.OnCommonRunning(i.Info);
                    }
                }
            });
            #endregion

            watch.Stop();
            timer.Change(int.Parse(_interval) + watch.ElapsedMilliseconds, Timeout.Infinite);
        }
        /// <summary>
        /// 准备开始运行
        /// </summary>
        /// <param name="system"></param>
        /// <returns></returns>
        public Stream Prepare(string system, out Guid runningID, out bool isRunning)
        {
            Stream code = null;
            runningID = Guid.Empty;
            isRunning = false;
            //代表账户已经运行
            var cnt = _running.SingleOrDefault(w => w.Info.System == system);
            if (cnt != null)
            {
                //如果canrun在运行，则表示运行中
                if (cnt.CanRun)
                {
                    isRunning = true;
                    return code;
                }
                else //则表示没运行，则直接删除
                {
                    _running.Remove(cnt);
                }
            }

            //根据系统类型，生成解析类
            var kasystem = KASystemFactory.GetSystem(system);
            kasystem.CompanyID = this.SysuserCompanyID;
            code = kasystem.GetLoginCode();
            if (code != null)
            {
                //准备运行信息
                runningID = Guid.NewGuid();
                var newinfo = new KASystemRunningModel
                {
                    System = system
                };
                RunningModel rm = new RunningModel
                {
                    ID = runningID,
                    Info = newinfo,
                    KASystem = kasystem,
                    PrepareTime = DateTime.Now
                };
                //添加到队列中准备
                lock (_toLock)
                {
                    _running.Add(rm);
                }
            }
            return code;
        }

        /// <summary>
        /// 添加到队列
        /// </summary>
        /// <param name="account"></param>
        public void Add(KASystemRunningModel account, Guid runningID)
        {
            if (IsLogin)
            {
                //找对解析类，进行复制。然后在线程中自动运行
                lock (_toLock)
                {
                    var system = _running.SingleOrDefault(r => r.ID == runningID && r.CanRun == false);
                    system.Info = account;
                }
            }
        }

        /// <summary>
        /// 停止
        /// </summary>
        /// <param name="account"></param>
        public void Stop()
        {
            IsLogin = false;
            timer.Dispose();
        }
    }
}
